package com.sky.config;

import com.sky.properties.AliOssProperties;
import com.sky.utils.AliOssUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;

import javax.swing.*;

/**
 * 配置类，用于创建AliOssUtil对象
 */
@Configuration//作用：表示当前类是一个配置类，可以创建对象，并交给Spring容器管理
@Slf4j
public class OssConfiguration {
    //不需要显式添加 @Autowired 注解。
//    原因如下：
//    构造器/方法参数的自动注入
//    在 Spring 中，当一个方法（包括构造方法）的参数需要依赖注入时，不需要显式添加 @Autowired 注解
//    javax.swing.Spring 会自动识别方法参数类型，并从容器中查找匹配的 Bean 进行注入
//    Spring 的智能注入机制
//    Spring 能够自动识别 AliOssProperties 类型的参数
//    容器中已经存在 AliOssProperties 的 Bean（因为它有 @Component 和 @ConfigurationProperties
//    注解）
//    Spring 会自动将该 Bean 注入到方法参数中
//    @Autowired AliOssProperties aliOssProperties;


    //在 OssConfiguration 类中使用 @Bean 注解的原因如下：
    //注册Bean到Spring容器
    //@Bean 注解用于将方法返回的对象注册为 Spring 容器管理的 Bean
    //这样其他组件就可以通过依赖注入的方式使用这个对象
    //创建和配置第三方组件
    //AliOssUtil 是一个第三方工具类，不是通过 @Component 等注解自动扫描注册的
    //需要通过 @Bean 方法手动创建并配置其实例
    //依赖注入优势
    //通过 @Bean 方法，可以自动注入所需的依赖（如 AliOssProperties）
    //Spring 会自动解析方法参数并注入相应的 Bean
    @Bean// 创建阿里云文件上传工具类对象
    @ConditionalOnMissingBean// 表示当前方法创建的对象，如果容器中已经存在这个对象，则不创建
    public AliOssUtil aliOssUtil(AliOssProperties aliOssProperties){
        log.info("开始创建阿里云文件上传工具类对象：{}", aliOssProperties);
         return new AliOssUtil(aliOssProperties.getEndpoint(),
                aliOssProperties.getAccessKeyId(), aliOssProperties.getAccessKeySecret(), aliOssProperties.getBucketName());
    }
}

//Spring Bean的初始化时机
//是的，OssConfiguration 配置类中的 aliOssUtil 方法在后端启动时会被运行，但有以下要点：
//条件执行：
//该方法带有 @Bean 注解，表明它用于创建Spring Bean
//同时使用了 @ConditionalOnMissingBean 注解，这意味着只有当Spring容器中不存在 AliOssUtil 类型的Bean时，才会执行该方法创建新实例
//执行时机：
//Spring在应用启动过程中会扫描所有带有 @Configuration 注解的配置类
//对于配置类中带有 @Bean 注解的方法，Spring会根据需要调用这些方法来创建和注册Bean
//在你的例子中，当Spring需要一个 AliOssUtil 实例且容器中尚不存在时，就会调用 aliOssUtil 方法
//依赖注入：
//方法参数 AliOssProperties aliOssProperties 会由Spring自动注入
//这个 AliOssProperties Bean必须已经存在于Spring容器中
//代码问题提醒： 你提供的代码中有一个问题：
